/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author mehadihasan
 */
import java.io.*;
import com.sun.jna.*;

public class Ren {

    public enum SE_OBJECT_TYPE {
          SE_UNKNOWN_OBJECT_TYPE,
          SE_FILE_OBJECT,
          SE_SERVICE,
          SE_PRINTER,
          SE_REGISTRY_KEY,
          SE_LMSHARE,
          SE_KERNEL_OBJECT,
          SE_WINDOW_OBJECT,
          SE_DS_OBJECT,
          SE_DS_OBJECT_ALL,
          SE_PROVIDER_DEFINED_OBJECT,
          SE_WMIGUID_OBJECT,
          SE_REGISTRY_WOW64_32KEY
    }
    public static class SECURITY_ATTRIBUTES extends Structure {

        public int nLength;
        public Pointer lpSecurityDescriptor;
        public boolean bInheritHandle;
    }

    public static class STARTUPINFO extends Structure {

        public STARTUPINFO() {
            cb=65;
        }

        public int cb;
        public Pointer lpReserved;
        public Pointer lpDesktop;
        public Pointer lpTitle;
        public int dwX;
        public int dwY;
        public int dwXSize;
        public int dwYSize;
        public int dwXCountChars;
        public int dwYCountChars;
        public int dwFillAttribute;
        public int dwFlags;
        public int wShowWindow;
        public int cbReserved2;
        public Pointer lpReserved2;
        public Pointer hStdInput;
        public Pointer hStdOutput;
        public Pointer hStdError;
    }

    public static class PROCESS_INFORMATION extends Structure {

        public Pointer hProcess;
        public Pointer hThread;
        public int dwProcessId;
        public int dwThreadId;
    }
    public static class JOBOBJECT_BASIC_LIMIT_INFORMATION extends Structure {
      public long PerProcessUserTimeLimit;
      public long PerJobUserTimeLimit;
      public int LimitFlags;
      public long MinimumWorkingSetSize;
      public long MaximumWorkingSetSize;
      public int ActiveProcessLimit;
      public Pointer Affinity;
      public int PriorityClass;
      public int SchedulingClass;
    }

    static interface Kernel32 extends Library {

        public static Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("Kernel32", Kernel32.class);
        public static int FORMAT_MESSAGE_FROM_SYSTEM = 4096;
        public static int FORMAT_MESSAGE_IGNORE_INSERTS = 512;
        public static int FORMAT_MESSAGE_ALLOCATE_BUFFER = 256;

        public boolean MoveFileW(WString lpExistingFileName,
                WString lpNewFileName);

        public int GetSecurityInfo(
              Pointer handle,
              SE_OBJECT_TYPE ObjectType,
              int SecurityInfo,
              Pointer ppsidOwner,
              Pointer ppsidGroup,
              Pointer ppDacl,
              Pointer ppSacl,
              Pointer ppSecurityDescriptor
        );
        public boolean SetInformationJobObject(Pointer hJob, int JobObjectInfoClass, JOBOBJECT_BASIC_LIMIT_INFORMATION lpJobObjectInfo, int cbJobObjectInfoLength);

        public Pointer CreateJobObjectW(SECURITY_ATTRIBUTES lpJobAttributes, WString lpName);

        public boolean AssignProcessToJobObject(Pointer hJob, Pointer hProcess);

        public boolean QueryInformationJobObject( Pointer hJob, int JobObjectInfoClass, JOBOBJECT_BASIC_LIMIT_INFORMATION lpJobObjectInfo,
                int cbJobObjectInfoLength,
                Pointer lpReturnLength
        );

        public Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, int dwProcessId);

        public boolean CreateProcessW(
                WString lpApplicationName,
                Pointer lpCommandLine,
                Pointer lpProcessAttributes,
                Pointer lpThreadAttributes,
                boolean bInheritHandles,
                int dwCreationFlags,
                String lpEnvironment,
                WString lpCurrentDirectory,
                Pointer lpStartupInfo,
                PROCESS_INFORMATION lpProcessInformation);

        public int ResumeThread(Pointer hThread);
        public int GetPriorityClass(Pointer hProcess);
        public boolean SetPriorityClass(Pointer hProcess,int dwPriorityClass);
        public boolean CloseHandle(Pointer hObject);
        public int GetLastError();

        public int FormatMessageW(int dwFlags,
                Pointer lpSource, int dwMessageId,
                int dwLanguageId, char[] lpBuffer, int nSize,
                Pointer Arguments);
    }

    public static String getLastError() {
        int dwMessageId = Kernel32.INSTANCE.GetLastError();
        char[] lpBuffer = new char[1024];
        int lenW = Kernel32.INSTANCE.FormatMessageW(
                Kernel32.FORMAT_MESSAGE_FROM_SYSTEM 
                | Kernel32.FORMAT_MESSAGE_IGNORE_INSERTS, null,
                dwMessageId, 0, lpBuffer, lpBuffer.length, null);
        return new String(lpBuffer, 0, lenW);
    }
}
